package com.eascs.web.p2p.pay.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Reference;
import com.eascs.app.dao.DefaultIdBuilder;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.p2p.common.entity.InvestorBankEntity;
import com.eascs.p2p.common.entity.InvestorEntity;
import com.eascs.p2p.common.entity.InvestorWalletPayEntity;
import com.eascs.p2p.common.entity.InvestorWithdrawRecordEntity;
import com.eascs.p2p.common.investor.service.InvestorBankService;
import com.eascs.p2p.common.service.InvestorService;
import com.eascs.p2p.common.vo.ModelResult;
import com.eascs.p2p.common.wallet.service.InvestorWalletService;
import com.eascs.web.p2p.common.security.Configuration;
import com.eascs.web.p2p.common.security.TZTService;

@Service
public class YeePayService {
	private static Logger logger = LoggerFactory.getLogger(YeePayService.class);

	@Reference
	InvestorService investorService;
	@Reference
	InvestorWalletService investorWalletService;
	@Reference
	InvestorBankService investorBankService;

	/** 用户标识类型 ID_CARD：用户身份证号 */
	public static final String IDENTITY_TYPE = "ID_CARD";
	/** 证件类型 固定值 ID：身份证 */
	public static final String IDCARD_TYPE = "ID";
	/**
	 * 订单状态status string(32) ACCEPT：已接收 TO_VALIDATE：待短验 BIND_FAIL：绑卡失败
	 * TO_ENHANCED：待补充鉴权 TIME_OUT：订单超时 FAIL：系统异常 BIND_SUCCESS：绑卡成功
	 * BIND_FAIL：绑卡失败 PAY_FAIL：支付失败 PROCESSING：处理中 PAY_SUCCESS：支付成功
	 * WITHDRAW_SUCCESS：提现成功 WITHDRAW_FAIL：提现失败
	 */
	public static final String ORDER_ACCEPT_TYPE = "ACCEPT";
	public static final String ORDER_TO_VALIDATE_TYPE = "TO_VALIDATE";
	public static final String ORDER_BIND_SUCCESS_TYPE = "BIND_SUCCESS";
	public static final String ORDER_BIND_FAIL_TYPE = "BIND_FAIL";
	public static final String ORDER_PROCESSING_TYPE = "PROCESSING";
	public static final String ORDER_PAY_FAIL_TYPE = "PAY_FAIL";
	public static final String ORDER_PAY_SUCCESS_TYPE = "PAY_SUCCESS";
	public static final String ORDER_WITHDRAW_FAIL_TYPE = "WITHDRAW_FAIL";
	public static final String ORDER_WITHDRAW_SUCCESS_TYPE = "WITHDRAW_SUCCESS";

	/*** 0：否 1：是 */
	public static final String YES = "1";
	public static final String NO = "0";
	/***/
	public static final String TERMINAL_TYPE = "app";
	/** 币种 (固定值) 156：人民币 */
	public static final String CURRENCY_TYPE = "156";
	/**
	 * NATRALDAY_NORMAL：自然日t+1 NATRALDAY_URGENT：自然日t+0
	 */
	public static final String NATRALDAY_NORMAL = "NATRALDAY_NORMAL";
	public static final String NATRALDAY_URGENT = "NATRALDAY_NORMAL";

	/** 绑定银行卡 **/
	public ModelResult<Boolean> bindCard(String realName, String idCardNo, String bankNo, InvestorEntity investor) {
		ModelResult<Boolean> result = new ModelResult<>();
		try {
			if (StringUtils.isBlank(realName) || StringUtils.isBlank(idCardNo) || StringUtils.isBlank(bankNo)
					|| investor == null) {
				logger.error("绑定银行卡失败，参数为空, realName:{}, idCardNo:{}, idBankNo:{}", realName, idCardNo, bankNo);
				return result.withError("YeePayService.bindCard", "绑定银行卡失败，参数为空");
			}
			Map<String, String> params = new HashMap<>();
			String requestno = DefaultIdBuilder.build();
			params.put("requestno", requestno);
			params.put("identityid", idCardNo);
			params.put("identitytype", IDENTITY_TYPE);
			params.put("cardno", bankNo);
			params.put("idcardno", idCardNo);
			params.put("idcardtype", IDCARD_TYPE);
			params.put("username", realName);
			params.put("phone", investor.getMobile());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String requesttime = sdf.format(new Date());
			params.put("requesttime", requesttime);
			Map<String, String> map = TZTService.bindCardRequest(params);
			String status = map.get("status");
			if (StringUtils.isBlank(status) || !ORDER_TO_VALIDATE_TYPE.equals(status)) {
				String errorcode = map.get("errorcode");
				String errormsg = map.get("errormsg");
				logger.error("绑定银行卡失败, status:{},errorcode:{},errormsg:{}", status, errorcode, errormsg);
				result.withError("YeePayService.bindCard", "绑定银行卡失败，errormsg：" + errormsg);
				return result;
			}
			InvestorBankEntity investorBank = new InvestorBankEntity();
			investorBank.setId(requestno);
			investorBank.setBankNo(bankNo);
			investorBank.setBankStatus(InvestorBankEntity.BANK_STATUS_VALIDATE);
			investorBank.setInvestorId(investor.getId());
			InvestorEntity investorUpdate = new InvestorEntity();
			investorUpdate.setId(investor.getId());
			investorUpdate.setUpdateTime(new Date());
			investorUpdate.setIdCardNo(idCardNo);
			investorUpdate.setName(realName);
			investorUpdate.setBankRequestno(requestno);
			ModelResult<Boolean> modelResult = investorBankService.investorBindBank(investorUpdate, investorBank);
			if (!modelResult.isSuccess() || !modelResult.getModel()) {
				logger.error("修改用户银行卡状态失败");
				result.withError("YeePayService.bindCard", "修改用户银行卡状态失败");
				return result;
			}
			result.withModel(true);
		} catch (Exception e) {
			logger.error("绑定银行卡失败, error:{}", e.getMessage());
			result.withError("YeePayService.bindCard", "绑定银行卡失败");
			e.printStackTrace();
			return result;
		}
		return result;
	}

	/** 绑卡确认银行卡 **/
	public ModelResult<Boolean> bindCardConfirm(String validatecode, InvestorEntity investor) {
		ModelResult<Boolean> result = new ModelResult<>();
		try {
			if (StringUtils.isBlank(validatecode) || investor == null) {
				logger.error("绑卡确认失败，参数为空, validatecode:{}, investor:{}, idBankNo:{}", validatecode, investor);
				return result.withError("YeePayService.bindCardConfirm", "绑卡确认失败，参数为空");
			}
			Map<String, String> params = new HashMap<>();
			params.put("requestno", investor.getBankRequestno());
			params.put("validatecode", validatecode);
			Map<String, String> map = TZTService.bindCardConfirm(params);
			String status = map.get("status");
			if (StringUtils.isBlank(status) || !ORDER_BIND_SUCCESS_TYPE.equals(status)) {
				String errorcode = map.get("errorcode");
				String errormsg = map.get("errormsg");
				logger.error("绑卡确认失败, status:{},errorcode:{},errormsg:{}", status, errorcode, errormsg);
				result.withError("YeePayService.bindCardConfirm", "绑卡确认失败，errormsg：" + errormsg);
				return result;
			}
			InvestorBankEntity investorBank = new InvestorBankEntity();
			investorBank.setId(investor.getBankRequestno());
			investorBank.setBankStatus(InvestorBankEntity.BANK_STATUS_YES);
			ModelResult<Boolean> modelResult = investorBankService.updateInvestorBank(investorBank);
			if (!modelResult.isSuccess() || !modelResult.getModel()) {
				logger.error("修改用户银行卡状态失败");
				result.withError("YeePayService.bindCard", "修改用户银行卡状态失败");
				return result;
			}
			result.withModel(true);
		} catch (Exception e) {
			logger.error("绑卡确认失败, error:{}", e.getMessage());
			result.withError("YeePayService.bindCardConfirm", "绑卡确认失败");
			e.printStackTrace();
			return result;
		}
		return result;
	}

	/** 重新获取绑卡验证码 **/
	public ModelResult<Boolean> bindCardResendsms(InvestorEntity investor) {
		ModelResult<Boolean> result = new ModelResult<>();
		try {
			if (investor == null) {
				logger.error("重新获取绑卡验证码失败，参数为空, investor:{}", investor);
				return result.withError("YeePayService.bindCardResendsms", "重新获取绑卡验证码失败，参数为空");
			}
			Map<String, String> params = new HashMap<>();
			params.put("requestno", investor.getBankRequestno());
			Map<String, String> map = TZTService.bindCardResendsms(params);
			String status = map.get("status");
			if (StringUtils.isBlank(status) || !ORDER_TO_VALIDATE_TYPE.equals(status)) {
				String errorcode = map.get("errorcode");
				String errormsg = map.get("errormsg");
				logger.error("重新获取绑卡验证码失败, status:{},errorcode:{},errormsg:{}", status, errorcode, errormsg);
				result.withError("YeePayService.bindCardResendsms", "重新获取绑卡验证码失败，errormsg：" + errormsg);
				return result;
			}
			result.withModel(true);
		} catch (Exception e) {
			logger.error("重新获取绑卡验证码失败, error:{}", e.getMessage());
			result.withError("YeePayService.bindCardResendsms", "重新获取绑卡验证码失败");
			e.printStackTrace();
			return result;
		}
		return result;
	}

	/** 无短充值 **/
	public ModelResult<Boolean> unSendBindPayRequest(String amount, InvestorEntity investor) {
		ModelResult<Boolean> result = new ModelResult<>();
		try {
			if (investor == null || StringUtils.isBlank(amount)) {
				logger.error("无短充值失败，参数为空, investor:{}, amount:{}, productname:{}", investor, amount);
				return result.withError("YeePayService.unSendBindPayRequest", "无短充值失败，参数为空");
			}
			ModelResult<InvestorBankEntity> investorBankMR = investorBankService.queryInvestorBankById(investor.getBankRequestno());
			if (investorBankMR == null) {
				logger.error("无短充值失败，无法获取银行卡信息, investor:{}, amount:{}, productname:{}", investor, amount);
				return result.withError("YeePayService.unSendBindPayRequest", "无短充值失败，无法获取银行卡信息");
			}
			InvestorBankEntity investorBank = investorBankMR.getModel();
			String bankNo = investorBank.getBankNo();
			Map<String, String> params = new HashMap<>();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String idCardNo = investor.getIdCardNo();
			//String lastLoginMac=investor.getLastLoginMac();TODO NIUX下获取MAX有问题
			String requestno = DefaultIdBuilder.build();
			params.put("requestno", requestno);
			params.put("identityid", idCardNo);
			params.put("identitytype", IDENTITY_TYPE);
			params.put("requesttime", sdf.format(new Date()));
			params.put("amount", amount);
			params.put("productname", requestno);
			params.put("cardtop", bankNo.substring(0, 6));
			params.put("cardlast", bankNo.substring(bankNo.length() - 4));
			params.put("terminalid", investor.getMobile());
			params.put("terminaltype", TERMINAL_TYPE);
			params.put("registtime", sdf.format(investor.getCreateTime()));
			params.put("registip", investor.getRegIp());
			params.put("lastloginip", investor.getLastLoginIp());
			params.put("lastlogintime", sdf.format(investor.getLastLoginTime()));
			params.put("lastloginterminalid", investor.getMobile());
			params.put("lastloginterminaltype", TERMINAL_TYPE);
			params.put("isthirdpartyuser", NO);
			params.put("issetpaypwd", YES);
			String callbackurl = Configuration.getInstance().getValue("unSendPayCallBackURL");
			params.put("callbackurl", callbackurl);
			Map<String, String> map = TZTService.unSendBindPayRequest(params);
			String status = map.get("status");
			if (StringUtils.isBlank(status)
					|| !(ORDER_ACCEPT_TYPE.equals(status) || ORDER_PROCESSING_TYPE.equals(status))) {
				String errorcode = map.get("errorcode");
				String errormsg = map.get("errormsg");
				logger.error("无短充值失败, status:{},errorcode:{},errormsg:{}", status, errorcode, errormsg);
				result.withError("YeePayService.unSendBindPayRequest", "无短充值失败，errormsg：" + errormsg);
				return result;
			}
			InvestorWalletPayEntity investorWalletPay = new InvestorWalletPayEntity();
			investorWalletPay.setId(requestno);
			investorWalletPay.setInvestorId(investor.getId());
			investorWalletPay.setStatus(InvestorWalletPayEntity.PAY_PROCESSING);
			investorWalletPay.setUpdateTime(new Date());
			investorWalletPay.setCreateTime(new Date());
			investorWalletPay.setAmount(new BigDecimal(amount));
			investorWalletService.insertInvestorWalletPay(investorWalletPay);
			result.withModel(true);
		} catch (Exception e) {
			logger.error("无短充值失败, error:{}", e.getMessage());
			result.withError("YeePayService.unSendBindPayRequest", "无短充值失败");
			e.printStackTrace();
			return result;
		}
		return result;
	}

	/** 无短充值回调 **/
	public ModelResult<Boolean> unSendBindPayRequestCallBack(String data, String encryptkey) {
		ModelResult<Boolean> result = new ModelResult<>();
		try {
			if (StringUtils.isBlank(data) || StringUtils.isBlank(encryptkey)) {
				logger.error("无短充值回调失败，参数为空,  data:{}, encryptkey:{}", data, encryptkey);
				return result.withError("YeePayService.unSendBindPayRequest", "无短充值回调失败，参数为空");
			}
			Map<String, String> map = TZTService.decryptCallbackData(data, encryptkey);
			String status = map.get("status");
			if (StringUtils.isBlank(status) || !ORDER_PAY_SUCCESS_TYPE.equals(status)) {
				String errorcode = map.get("errorcode");
				String errormsg = map.get("errormsg");
				logger.error("无短充值失败, status:{},errorcode:{},errormsg:{}", status, errorcode, errormsg);
				result.withError("YeePayService.unSendBindPayRequest", "无短充值失败，errormsg：" + errormsg);
				return result;
			}
			// 充值流水记录
			String requestno = map.get("requestno");
			ModelResult<Boolean> modelResult = investorWalletService.investorWalletPay(requestno);
			if (modelResult.isSuccess() && modelResult.getModel()) {
				result.withModel(true);
			} else {
				logger.error("无短充值失败,充值流水记录报错, requestno:{}", requestno);
				result.withError("YeePayService.unSendBindPayRequest", "无短充值失败,充值流水记录报错");
				return result;
			}
		} catch (Exception e) {
			logger.error("无短充值回调失败, error:{}", e.getMessage());
			result.withError("YeePayService.unSendBindPayRequestCallBack", "无短充值回调失败");
			e.printStackTrace();
			return result;
		}
		return result;
	}

	/** 提现 **/
	public ModelResult<Boolean> withdraw(String amount, InvestorEntity investor) {
		ModelResult<Boolean> result = new ModelResult<>();
		try {
			if (investor == null || StringUtils.isBlank(amount)) {
				logger.error("提现失败，参数为空, investor:{}, amount:{}", investor, amount);
				return result.withError("YeePayService.withdraw", "提现失败，参数为空");
			}
			ModelResult<InvestorBankEntity> investorBankMR = investorBankService.queryInvestorBankById(investor.getBankRequestno());
			if (investorBankMR == null) {
				logger.error("提现失败，无法获取银行卡信息, investor:{}, amount:{}", investor, amount);
				return result.withError("YeePayService.withdraw", "提现失败，无法获取银行卡信息");
			}
			InvestorBankEntity investorBank = investorBankMR.getModel();
			String bankNo = investorBank.getBankNo();
			Map<String, String> params = new HashMap<>();
			String requestno = DefaultIdBuilder.build();
			String idCardNo = investor.getIdCardNo();
			params.put("requestno", requestno);
			params.put("identityid", idCardNo);
			params.put("identitytype", IDENTITY_TYPE);
			params.put("cardtop", bankNo.substring(0, 6));
			params.put("cardlast", bankNo.substring(bankNo.length() - 4));
			params.put("amount", amount);
			params.put("currency", CURRENCY_TYPE);
			params.put("drawtype", NATRALDAY_URGENT);
			String callbackurl = Configuration.getInstance().getValue("withdrawCallBackURL");
			params.put("callbackurl", callbackurl);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			params.put("requesttime", sdf.format(new Date()));
			params.put("userip", investor.getRegIp());
			Map<String, String> map = TZTService.withdraw(params);
			String status = map.get("status");
			if (StringUtils.isBlank(status) || ORDER_WITHDRAW_FAIL_TYPE.equals(status)) {
				String errorcode = map.get("errorcode");
				String errormsg = map.get("errormsg");
				logger.error("提现失败, status:{},errorcode:{},errormsg:{}", status, errorcode, errormsg);
				result.withError("YeePayService.withdraw", "提现失败，errormsg：" + errormsg);
				return result;
			}
			InvestorWithdrawRecordEntity withdrawRecord = new InvestorWithdrawRecordEntity();
			withdrawRecord.setRequestno(requestno);
			withdrawRecord.setStatus(InvestorWithdrawRecordEntity.STATUS_PROCESSING_WITHDRAW);
			investorWalletService.updateWithdrawRecord(withdrawRecord);
			result.withModel(true);
		} catch (Exception e) {
			logger.error("提现失败, error:{}", e.getMessage());
			result.withError("YeePayService.withdraw", "提现失败");
			e.printStackTrace();
			return result;
		}
		return result;
	}

	/** 提现回调 **/
	public ModelResult<Boolean> withdrawCallBack(String data, String encryptkey) {
		ModelResult<Boolean> result = new ModelResult<>();
		try {
			if (StringUtils.isBlank(data) || StringUtils.isBlank(encryptkey)) {
				logger.error("提现回调失败，参数为空,  data:{}, encryptkey:{}", data, encryptkey);
				return result.withError("YeePayService.withdrawCallBack", "提现回调失败，参数为空");
			}
			Map<String, String> map = TZTService.decryptCallbackData(data, encryptkey);
			String status = map.get("status");
			if (StringUtils.isBlank(status) || !ORDER_WITHDRAW_SUCCESS_TYPE.equals(status)) {
				String errorcode = map.get("errorcode");
				String errormsg = map.get("errormsg");
				logger.error("提现回调失败, status:{},errorcode:{},errormsg:{}", status, errorcode, errormsg);
				result.withError("YeePayService.withdrawCallBack", "提现回调失败，errormsg：" + errormsg);
				return result;
			}
			// 充值流水记录
			String requestno = map.get("requestno");
			ModelResult<Boolean> modelResult = investorWalletService.investorWalletWithdrawConfirm(requestno);
			if (modelResult.isSuccess() && modelResult.getModel()) {
				result.withModel(true);
			} else {
				logger.error("提现回调失败,充值流水记录报错, requestno:{}", requestno);
				result.withError("YeePayService.withdrawCallBack", "提现回调失败,充值流水记录报错");
				return result;
			}
		} catch (Exception e) {
			logger.error("提现回调失败, error:{}", e.getMessage());
			result.withError("YeePayService.withdrawCallBack", "提现回调失败");
			e.printStackTrace();
			return result;
		}
		return result;
	}

}
